#include "game.h"
#include <cassert>

namespace vkrender
{
    Game::Game()
    {
        window = std::make_shared<VulkanWindow>(1280, 720, "vkrender");
        context = std::make_shared<VulkanDeviceContext>(window);
        recreateSwapchain();
        render_base = std::make_shared<RenderSystem>(context, swapchain);
    }

    Game::~Game()
    {

    }

    void Game::run()
    {
        while (!window->shouldClose())
        {
            glfwPollEvents();
            draw();
        }
        vkDeviceWaitIdle(context->device);
    }

    void Game::draw()
    {
        bool ret = render_base->beginFrame();
        if (!ret)
        {
            window->resetResizedFlag();
            recreateSwapchain();
            render_base->adjustForSwapchain(swapchain);
        }

        VkExtent2D ext = window->getExtent();
        if (ext.width > 0 && ext.height > 0)
        {
            render_base->DrawScene(ext);
        }

        ret = render_base->endFrame();
        if (!ret)
        {
            window->resetResizedFlag();
            recreateSwapchain();
            render_base->adjustForSwapchain(swapchain);
        }
    }

    void Game::recreateSwapchain()
    {
        auto extent = window->getExtent();

        while (extent.width == 0 || extent.height == 0)
        {
            extent = window->getExtent();
            glfwWaitEvents();
        }
        vkDeviceWaitIdle(context->device);

        if (swapchain == nullptr)
        {
            swapchain = std::make_shared<VulkanSwapChain>(context, extent);
        }
        else
        {
#if 1
            // no two swapchain can exists simultaneously
            auto ptr = swapchain.get();
            swapchain.reset();
            swapchain = std::make_shared<VulkanSwapChain>(context, extent);
#else
            swapchain->recreate(extent);
#endif
        }
    }

}
